import mmap
import re
import time


class MemStruct:
    """最大参数长度是60个字符，换算成汉字是30"""

    def __init__(self, max_u_length=200):
        self.single_length = max_u_length * 3
        self.prms = []
        self.span = b"\x00"
        self.exp = re.compile('\x00*$')

    def clear(self):
        self.prms.clear()

    def add_prm(self, prm):
        if isinstance(prm, list):
            self.prms.extend(prm)
        else:
            self.prms.append(prm)

    def _to_byte(self, prm):
        _b = str(prm).encode(encoding='UTF-8')
        assert len(_b) < self.single_length, "参数长度大于最大限制了"
        remain = self.single_length - len(_b)
        _b = _b + self.span * remain
        return _b

    def _prm_to_cn_txt(self, prm):
        cn_txt = str(prm, 'utf-8', 'ignore')
        cn_txt = self.exp.sub('', cn_txt)
        return cn_txt

    def to_bytes(self):
        out_list = b''
        for i, b in enumerate(self.prms):
            out_list += self._to_byte(b)
        return out_list

    def to_utf8(self, byte_obj):
        '''会去掉末尾的空行'''
        out_lst = []
        lens = len(byte_obj) // self.single_length
        for i in range(lens):
            start = i * self.single_length
            t = byte_obj[start: start + self.single_length]
            cntxt = self._prm_to_cn_txt(t)
            if len(cntxt)>0:
                out_lst.append(cntxt)
        return out_lst


class MemoryShareHelper:
    def __init__(self, file_name="global_share_memory", max_length=40960):
        self.FILE_NAME = file_name
        self.exp = re.compile('\x00*$')
        self.MAX_MEMORY_SIZE = max(len(file_name), max_length)
        self._write_memory_tool = mmap.mmap(0, self.MAX_MEMORY_SIZE, self.FILE_NAME, mmap.ACCESS_WRITE)
        self._read_memory_tool = mmap.mmap(0, self.MAX_MEMORY_SIZE, self.FILE_NAME, mmap.ACCESS_READ)
        self.mem_struct = MemStruct()

    def write_txt_to_memory(self, txt):
        '''
        单行写入内存
        Parameters
        ----------
        txt

        Returns
        -------

        '''
        byte = txt.encode(encoding='UTF-8')
        # python写入共享内存
        try:
            self._write_memory_tool.write(byte)
        except Exception as e:
            print("超出最大限制", e)

    def add_text_to_list(self, txt):
        '''
        待写入的字符加入到列表中
        Parameters
        ----------
        txt

        Returns
        -------

        '''
        self.mem_struct.add_prm(txt)

    def list_to_memory(self):
        '''列表写入到内存中'''
        _bytes = self.mem_struct.to_bytes()
        self.write_byte_to_memory(_bytes)
        self.mem_struct.clear()

    def write_byte_to_memory(self, byte_obj):
        '''
        字节写入内存中，单行写人
        Parameters
        ----------
        byte_obj

        Returns
        -------

        '''
        try:
            self._write_memory_tool.write(byte_obj)
        except Exception as e:
            print("超出最大限制", len(byte_obj) ,e)

    def read_txt_list_from_memory(self):
        """
        读出一个list
        Returns
        -------

        """
        data = self._read_memory_tool.read(self.MAX_MEMORY_SIZE)
        cn_txt = self.mem_struct.to_utf8(data)
        return cn_txt

    def read_cn_txt_from_memory(self):
        '''
        读单独的一行
        Returns
        -------

        '''
        data = self._read_memory_tool.read(self.MAX_MEMORY_SIZE)
        cn_txt = str(data, 'utf-8', 'ignore')
        cn_txt = self.exp.sub('', cn_txt)
        return cn_txt

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._read_memory_tool.close()
        self._write_memory_tool.close()


if __name__ == '__main__':
    ms = MemoryShareHelper()
    x = '测lalala啦啦啦啦adssddf啦大试.jpg'
    ms.add_text_to_list(x)
    ms.add_text_to_list("测试记测试nihao&9087^(^*$(*97录")
    ms.add_text_to_list("玩哈哈")
    ms.add_text_to_list("你干啥，阿斯顿发斯蒂芬")


    ms.list_to_memory()
    c = ms.read_txt_list_from_memory()
    print(c)
    time.sleep(10)  # 程序退出后内存中就没东西了
